// Copyright (C) 2023 即时通讯网(52im.net) & Jack Jiang.
// The RainbowChat Project. All rights reserved.
// 
// 【本产品为著作权产品，合法授权后请放心使用，禁止外传！】
// 【本次授权给：<北京小羊驼科技有限公司>，授权编号：<NT231212144350>，代码指纹：<A.702363430.550>，技术对接人微信：<ID: wxid_wbyootvkdcgj22>】
// 【授权寄送：<收件：苏先生、地址：北京市大兴区北京密码西区6号楼1单元301、电话：18613885610、邮箱：bd@huiyuanxiang-inc.com>】
// 
// 【本系列产品在国家版权局的著作权登记信息如下】：
// 1）国家版权局登记名(简称)和权证号：RainbowChat    （证书号：软著登字第1220494号、登记号：2016SR041877）
// 2）国家版权局登记名(简称)和权证号：RainbowChat-Web（证书号：软著登字第3743440号、登记号：2019SR0322683）
// 3）国家版权局登记名(简称)和权证号：RainbowAV      （证书号：软著登字第2262004号、登记号：2017SR676720）
// 4）国家版权局登记名(简称)和权证号：MobileIMSDK-Web（证书号：软著登字第2262073号、登记号：2017SR676789）
// 5）国家版权局登记名(简称)和权证号：MobileIMSDK    （证书号：软著登字第1220581号、登记号：2016SR041964）
// * 著作权所有人：江顺/苏州网际时代信息科技有限公司
// 
// 【违法或违规使用投诉和举报方式】：
// 联系邮件：jack.jiang@52im.net
// 联系微信：hellojackjiang
// 联系QQ号：413980957
// 授权说明：http://www.52im.net/thread-1115-1-1.html
// 官方社区：http://www.52im.net
package com.x52im.rainbowchat.http.logic;

import net.x52im.mobileimsdk.server.processor.OnlineProcessor;
import net.x52im.mobileimsdk.server.protocal.Protocal;
import net.x52im.mobileimsdk.server.protocal.ProtocalFactory;

import com.alibaba.fastjson.JSONObject;
import com.eva.epc.common.util.CommonUtils;
import com.eva.framework.Processor;
import com.eva.framework.dbpool.DBShell;
import com.eva.framework.dto.SysActionConst;
import com.eva.framework.utils.EndsExceptionFactory;
import com.eva.framework.utils.LoggerFactory;
import com.x52im.rainbowchat.common.dto.cnst.UserProtocalsType;
import com.x52im.rainbowchat.im.impl.ChatLogicManager;

/**
 * 服务端对外提供的实时消息推送等特权接口处理器。
 * <p>
 * 此处理器内的接口均为用于管理端的特权接口，原则上客户端禁止调用。
 * 
 * @author Jack Jiang(http://www.52im.net/space-uid-1.html)
 * @version 1.0
 * @since 4.0
 */
public class IMAdminProcessor implements SysActionConst, Processor
{
	public static DBShell db = new DBShell();
	
	/**
	 * 处理器的核心实现方法.<br>
	 * 可据job_dispatch_id找到对应的JobDispatcher，JobDispatcher又能据
	 * action_id进行对应动作的处理，以完成本次操作请求.
	 * 
	 * @param job_dispatch_id 作业调度ID
	 * @param action_id 动作ID
	 * @param Object newData 客端发送过来的本次修改新数据(可能为空，理论上与oldData不会同时空）
	 * @param Object oldData 客端发送过来的本次修改前的老数据(可能为空，理论上与newData不会同时空）
	 * @param UserRoot user 包含该请求用户完整个人信息封装对象（该对象来自于成功登陆后存放于session中的值）
	 * @return 任意类型返回值
	 * @throws Exception
	 */
	@Override public Object process(int job_dispatch_id, int action_id, Object _newData, Object _oldData, User user)
			throws Exception
	{
		Object ret = null;
		String newDataJSON = (String)_newData;
		
		switch (job_dispatch_id)
		{	
			// 处理服务端对外提供的实时消息推送接口的管理
			case com.x52im.rainbowchat.http.logic.dto.JobDispatchConst.LOGIC_MSG$PUSH:
				ret = maintainMgrMsg$PushJobDispatcher(action_id, newDataJSON, _oldData , user);
				break;

			default:
				throw EndsExceptionFactory.INVALID_JOB_DISPATCHER_ID(job_dispatch_id);
		}
		return ret;
	}
	
	/** 
	 * 维护服务端对外提供的实时消息推送接口的管理.
	 * 
	 * @param action_id 维护类型，SysConstant中的操作类型常量
	 * @param newDataJSON 客端发送过来的本次修改新数据(可能为空，理论上与oldData不会同时空）
	 * @param oldData 客端发送过来的本次修改前的老数据(可能为空，理论上与newData不会同时空）
	 * @param user 操作者的用户信息
	 * @return 返回给客户端的对象
	 */
	public Object maintainMgrMsg$PushJobDispatcher(int action_id, String newDataJSON, Object oldData, User user) throws Exception
	{
		switch (action_id)
		{
			// 向指定客户端推送一条消息或指令（目前暂时用作网页管理端调用，请注意安全性）
			case ACTION_APPEND1:
			{
				// 客户端传过来的数据
				JSONObject nwObj = JSONObject.parseObject(newDataJSON);
				
				// 消息发送者的uid（必须是RainbowChat用户表中已存在的用户）
				String from = nwObj.getString("from");
				// 消息接收者的uid（必须是RainbowChat用户表中已存在的用户）
				String to = nwObj.getString("to");
				// 消息内容，是 MsgBody4Guest 类的JSON文本内容
				// 见：http://docs.52im.net/extend/docs/api/rainbowchatserver4_pro/com/x52im/rainbowchat/im/dto/MsgBody4Guest.html
				String dataContent = nwObj.getString("dataContent");
				// 0 表示false、1表示true，建议填“1”
				boolean QoS = "1".equals(nwObj.getString("QoS"));// 0 表示false、1表示true
				// 消息类型，参见：MsgBodyRoot 类中的“聊天消息类型”常量定义
				// 见：http://docs.52im.net/extend/docs/api/rainbowchatserver4_pro/com/x52im/rainbowchat/im/dto/MsgBodyRoot.html
				int typeu = CommonUtils.getIntValue(nwObj.getString("typeu"), -1);
				
				boolean result = false;
				
				// 如果是模拟客户端发送临时聊天消息则调用以下方法
				if(typeu == UserProtocalsType.MT43_OF_TEMP$CHAT$MSG_SERVER$TO$B)
				{
					// 以下方法是完整的RainbowChat临时聊天消息发送方式，包含了离线处理等异常情况
					result = ChatLogicManager.processMT42_OF_TEMP$CHAT$MSG_A$TO$SERVER(Protocal.genFingerPrint(), dataContent);
				}
				// 其它特权消息请根据实际情况决定是否要离线处理等特殊情况
				else
				{
					Protocal p = ProtocalFactory.createCommonData(dataContent
							, from, to, QoS, Protocal.genFingerPrint(), typeu);
					
					// 首先判断消息接收者是否在线
					if(OnlineProcessor.isOnline(to))
					{
						// 以下方法是用于实时消息发送的
//						result = MessageHelper.sendMessage(from, to, dataContent, QoS, typeu);
//						result = LocalSendHelper.sendData(p);
						result = true;
					}
					// 如果接收者不在线的话，特权指令的处理情况有待进一步约定
					else
					{
						LoggerFactory.getLog().warn("【特权接口】向客户端"+to
								+"推送的消息因对方不在线而不能实时发送，应针对不同" +
								"的特权消息类型考虑离线情况下的处理哦(dataContent="+dataContent+")");

						// TODO 不同类型的特权消息发送需要进一步处理哦！
					}
				}

				return result?"1":"0";
			}
			
			default:
				throw EndsExceptionFactory.INVALID_ACTION_ID(action_id);
		}
	}
}
